﻿#include "DAWorkFlowGraphicsView.h"
#include <QDragEnterEvent>
#include <QDebug>
#include <QKeyEvent>
#include "DAAbstractNode.h"
#include "DANodeMimeData.h"
#include "DANodeMetaData.h"
#include "DAMimeTypeFormatDefine.h"
#include "DAWorkFlowGraphicsScene.h"

DAWorkFlowGraphicsView::DAWorkFlowGraphicsView(QWidget *parent) : DANodeGraphicsView(parent)
{
    setAcceptDrops(true);
    DAWorkFlowGraphicsScene *sc = new DAWorkFlowGraphicsScene(this);

    setScene(sc);
    setRenderHint(QPainter::Antialiasing, false);
    // setDragMode(QGraphicsView::RubberBandDrag);
    setOptimizationFlags(QGraphicsView::DontSavePainterState);
    setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
    setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
    connect(sc, &DAWorkFlowGraphicsScene::selectionChanged, this, &DAWorkFlowGraphicsView::onSceneSelectionChanged);
}

DAWorkFlowGraphicsView::DAWorkFlowGraphicsView(QGraphicsScene *scene, QWidget *parent)
    : DANodeGraphicsView(scene, parent)
{
    setAcceptDrops(true);
}

/**
 * @brief 设置工程
 * @param project
 */
void DAWorkFlowGraphicsView::setProject(DAProject *project)
{
    m_project = project;
}

void DAWorkFlowGraphicsView::setNodeFactory(DADataWorkFlow *factory)
{
    m_workflow = factory;
}

void DAWorkFlowGraphicsView::dragEnterEvent(QDragEnterEvent *e)
{
    if (e->mimeData()->hasFormat(MIME_NODE_META_DATA)) {
        //说明有节点的meta数据拖入
        e->acceptProposedAction();
    } else {
        e->ignore();
    }
}

void DAWorkFlowGraphicsView::dragMoveEvent(QDragMoveEvent *e)
{
    e->acceptProposedAction();
}

void DAWorkFlowGraphicsView::dropEvent(QDropEvent *e)
{
    if (e->mimeData()->hasFormat(MIME_NODE_META_DATA)) {
        //说明有节点的meta数据拖入
        const DANodeMimeData *nodemime = qobject_cast<const DANodeMimeData *>(e->mimeData());
        if (nullptr == nodemime) {
            qDebug() << tr("drop have invalid mime data");
            return;
        }
        QGraphicsScene *sc = scene();
        DANodeMetaData nodemeta = nodemime->getNodeMetaData();
        DAAbstractNode::Pointer node = m_workflow->createNode(nodemeta);
        if (nullptr == node) {
            qDebug() << tr("can not create node,node prototype is:") << node->getNodePrototype();
            return;
        }
        static unsigned int s_node_count = 0;
        ++s_node_count;
        node->setNodeName(QStringLiteral("node_%1").arg(s_node_count));
        DAAbstractNodeGraphicsItem *item = node->createGraphicsItem();
        QPointF pos = mapToScene(e->pos());
        item->setPos(pos);
        sc->addItem(item);
    }
}

void DAWorkFlowGraphicsView::keyPressEvent(QKeyEvent *keyEvent)
{
    if (nullptr == keyEvent) {
        return;
    }

    switch (keyEvent->key()) {
    case Qt::Key_Delete:
        onDeletePressed();
        break;

    default:
        break;
    }
    DANodeGraphicsView::keyPressEvent(keyEvent);
}

void DAWorkFlowGraphicsView::onSceneSelectionChanged()
{
    DAWorkFlowGraphicsScene *sc = qobject_cast<DAWorkFlowGraphicsScene *>(scene());

    if (nullptr == sc) {
        return;
    }
    DAAbstractNodeGraphicsItem *item = sc->getSelectedNodeGraphicsItem();

    if (item == nullptr) {
        return;
    }
    emit selectNodeItemChanged(item);
}

void DAWorkFlowGraphicsView::onDeletePressed()
{
    DAWorkFlowGraphicsScene *sc = qobject_cast<DAWorkFlowGraphicsScene *>(scene());

    if (nullptr == sc) {
        return;
    }
}
